package org.gaeswf
{
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.mxml.RemoteObject;
	
	import net.ba.models.Model;
	

	
	
	public class ServiceRO
	{
		public static var ro:RemoteObject;
		private static var inited:Boolean = false;
		private static var listeners:Object;
				
		static public function call(serviceName:String, listener:Object, ...args):void {
			init();
			listen(serviceName, listener);
			var serviceCall:ServiceCallRO = new ServiceCallRO(serviceName, args);	
			
		}
		
		public static function listen(serviceName:String, listener:Object):void
		{
			// Initialize, if not already initialized.
			init();
			
			// Add listener.
			if (listeners[serviceName] == null)
			{
				listeners[serviceName] = new Array();
			}
			
			// Check that we don't add multiple listeners
			var l:Array = listeners[serviceName];
			var numListeners:uint = l.length;
			var found:Boolean = false;
			for (var i:uint = 0; i < numListeners; i++)
			{
				if (l[i] == listener) 
				{
					found = true;
					break;
				}
			}
			if (found) return;
			
			// Listener does not exist, add it.
			l.push(listener);
			
		}
		
		private static function init():void
		{
			
			if (!inited) {
				listeners = new Object();
				
				ro = new RemoteObject("amfphp");
				ro.endpoint = Model.amfSpatialEndPoint;
				
				inited = true;
			}
			
		}
		// Returns a handler name from a given service name and handler type. 
		private static function getHandlerName(serviceName:String, handlerType:String):String
		{
			return serviceName.replace(/\./, "_") + handlerType;
		}

		// Notify listeners that a response or fault has occured on the 
		// service that they are listening for. 
		private static function notifyListeners(serviceName:String, handlerType:String, eventObj:Object):void
		{
			var handlerName:String = getHandlerName(serviceName, handlerType);			
			
			var serviceListeners:Array = listeners[serviceName];
			var numServiceListeners:uint = serviceListeners.length;
			
			for (var i:uint = 0; i < numServiceListeners; i++)
			{
				var handlerObj:Object = serviceListeners[i];
				
				if (handlerObj.hasOwnProperty(handlerName))
				{
					handlerObj[handlerName].apply(handlerObj, [eventObj]);					
				}
				else
				{
					trace ("Warning: No " + handlerName + " found on " + handlerObj);
				}
			}
		}
		
		//
		// Event handlers (public; called by ServiceCall instances.)
		//
		
		public static function responseHandler(serviceName:String, result:Object):void
		{
			// Notify listeners
			notifyListeners(serviceName, "Response", result);
		}
		
		public static function faultHandler(serviceName:String, fault:Object):void
		{
			trace ("Service fault: ");
			for (var i:String in fault)
			{
				trace (i + " = " + fault[i])
			}
			
			// Notify listeners
			notifyListeners(serviceName, "Fault", fault);
		}

	}
}